package com.ym.medical.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.RandomUtil;
import com.ym.common.constant.DictEnum;
import com.ym.common.utils.StringUtil;
import com.ym.core.utils.tkmybatis.BaseSVImpl;
import com.ym.medical.dao.SysCodeRuleDao;
import com.ym.medical.domain.entity.SysCodeRuleEntity;
import com.ym.medical.domain.param.SysCodeRuleQueryParam;
import com.ym.medical.domain.param.SysCodeRuleUpdateParam;
import com.ym.medical.domain.vo.SysCodeRuleListPcVO;
import com.ym.medical.enums.CodeRuleEnum;
import com.ym.medical.enums.CodeRuleTypeEnum;
import com.ym.medical.service.ISysCodeRuleSV;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 编码生产Service业务层处理
 *
 * @author ym
 * @date 2020-08-17
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysCodeRuleSVImpl extends BaseSVImpl<SysCodeRuleEntity, SysCodeRuleDao> implements ISysCodeRuleSV {

	/**
	 * 查询编码生产列表
	 *
	 * @param queryParam 编码生产 查询参数
	 * @return 编码生产
	 */
	@Override
	public List<SysCodeRuleListPcVO> selectListPC(SysCodeRuleQueryParam queryParam) {
		List<SysCodeRuleListPcVO> sysCodeRules = mapper.selectListPC(queryParam);
		return sysCodeRules;
	}

	/**
	 * 新增编码生产
	 *
	 * @param updateParam 编码生产 新增参数
	 * @return 结果
	 */
	@Override
	public Long insertPC(SysCodeRuleUpdateParam updateParam) {
		SysCodeRuleEntity entity = updateParam.covert();
		this.insert(entity);
		return entity.getId();
	}

	/**
	 * 修改编码生产
	 *
	 * @param updateParam 编码生产 修改参数
	 * @return 结果
	 */
	@Override
	public int updateByIdPC(SysCodeRuleUpdateParam updateParam) {
		SysCodeRuleEntity entity = updateParam.covert();
		int result = this.updateById(entity);
		return result;
	}

	@Override
	public String createCode(CodeRuleEnum ruleCode) {
		String code = null;
		SysCodeRuleEntity sysCodeRuleEntity = this.selectOne(Select().forUpdate().where().andEqualTo(SysCodeRuleEntity::getRuleCode, ruleCode.getCode()).end());
		if (sysCodeRuleEntity == null) {
			// 不存在
			return code;
		}
		// 判断规则
		CodeRuleTypeEnum codeRuleTypeEnum =  DictEnum.valueOfEnum(CodeRuleTypeEnum.class, sysCodeRuleEntity.getFormatType());
		switch (codeRuleTypeEnum) {
			case TIME_RANDOM:
				code = this.timeRandom(sysCodeRuleEntity);
				break;
			case SERIAL:
				code = this.serial(sysCodeRuleEntity);
				break;
			case TIME_SERIAL:
				code = this.timeSerial(sysCodeRuleEntity);
				break;
		}
		this.updateById(sysCodeRuleEntity);
		return code;
	}

	/**
	 * 时间加序列方式
	 *
	 * @param sysCodeRuleEntity
	 * @return
	 */
	private String timeSerial(SysCodeRuleEntity sysCodeRuleEntity) {
		StringBuilder code = new StringBuilder();
		SimpleDateFormat sdf = new SimpleDateFormat(sysCodeRuleEntity.getFormat());
		String curMonth = sdf.format(new Date());
		if (!curMonth.equals(sysCodeRuleEntity.getCurFormatVal())) {
			// 当前值不相等，重置从1开始
			sysCodeRuleEntity.setSerial(1L);
		}
		sysCodeRuleEntity.setCurFormatVal(curMonth);
		if (StringUtil.isNotBlank(sysCodeRuleEntity.getCodePrefix())) {
			code.append(sysCodeRuleEntity.getCodePrefix());
		}
		code.append(sysCodeRuleEntity.getCurFormatVal());
		String num = String.format("%0" + sysCodeRuleEntity.getSerialLength() + "d", sysCodeRuleEntity.getSerial());
		code.append(num);
		// 序号+1
		sysCodeRuleEntity.setSerial(sysCodeRuleEntity.getSerial() + 1);
		return code.toString();
	}

	/**
	 * 只是序列
	 *
	 * @param sysCodeRuleEntity
	 * @return
	 */
	private String serial(SysCodeRuleEntity sysCodeRuleEntity) {
		StringBuilder code = new StringBuilder();
		if (StringUtil.isNotBlank(sysCodeRuleEntity.getCodePrefix())) {
			code.append(sysCodeRuleEntity.getCodePrefix());
		}
		String num = String.format("%0" + sysCodeRuleEntity.getSerialLength() + "d", sysCodeRuleEntity.getSerial());
		code.append(num);
		// 序号+1
		sysCodeRuleEntity.setSerial(sysCodeRuleEntity.getSerial() + 1);
		return code.toString();
	}

	/**
	 * 日期加随机数
	 *
	 * @param sysCodeRuleEntity
	 * @return
	 */
	private String timeRandom(SysCodeRuleEntity sysCodeRuleEntity) {
		StringBuilder code = new StringBuilder();
		SimpleDateFormat sdf = new SimpleDateFormat(sysCodeRuleEntity.getFormat());
		String curMonth = sdf.format(new Date());
		sysCodeRuleEntity.setCurFormatVal(curMonth);
		if (StringUtil.isNotBlank(sysCodeRuleEntity.getCodePrefix())) {
			code.append(sysCodeRuleEntity.getCodePrefix());
		}
		code.append(sysCodeRuleEntity.getCurFormatVal());
		// 获取当前时间的秒+毫秒
		String num = "";
		DateTime now = DateTime.now();
		int diff = sysCodeRuleEntity.getSerialLength() - 5;
		int second = now.getField(DateField.SECOND);
		int millisecond = now.getField(DateField.MILLISECOND);
		if (diff > 0) {
			num += RandomUtil.randomNumbers(diff);
		}
		code.append(num + second + millisecond);
		return code.toString();
	}

	@Override
	public String selectByIoNum(String outTradeNo) {
		return mapper.selectByIoNum(outTradeNo);
	}

}
